package org.mii.safeguard_v1.security.service.mdef;

import java.util.LinkedHashMap;
import java.util.List;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.mii.safeguard_v1.security.entity.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.ConfigAttributeEditor;
import org.springframework.security.intercept.AbstractSecurityInterceptor;
import org.springframework.security.intercept.InterceptorStatusToken;
import org.springframework.security.intercept.ObjectDefinitionSource;
import org.springframework.security.intercept.method.MethodDefinitionSource;

/**
 * 方法保护用拦截器
 * @author Saya
 *
 */
public class MethodSecurityInterceptor extends AbstractSecurityInterceptor implements MethodInterceptor{
	
	private static MethodDefinitionSource objectDefinitionSource;
	private static final String AUTHORITY_TYPE = "method";
	@Autowired
	private ISecurityInterceptor securityInterceptor;
	
	@SuppressWarnings("unchecked")
    public Class getSecureObjectClass() {
        return MethodInvocation.class;
    }
	
	public Object invoke(MethodInvocation mi) throws Throwable {
        Object result = null;
        InterceptorStatusToken token = super.beforeInvocation(mi);

        try {
            result = mi.proceed();
        } finally {
            result = super.afterInvocation(token, result);
        }

        return result;
    }
	
	/**
     * 初始化MethodDefinitionSource对象，为Method拦截器提供验证访问。
     * 
     */
    public ObjectDefinitionSource obtainObjectDefinitionSource() {
        if(objectDefinitionSource == null){
            AspectJMethodMatcher methodMatcher = new AspectJMethodMatcher();
            LinkedHashMap<String, ConfigAttributeDefinition> methodMap
                    = new LinkedHashMap<String, ConfigAttributeDefinition>();
            
            List<Resource> resources = securityInterceptor.loadResources(AUTHORITY_TYPE);
            methodMap = new LinkedHashMap<String, ConfigAttributeDefinition>();
            for (Resource resource : resources) {
                String grantedAuthorities = resource.getAuthNames();
                if (grantedAuthorities != null) {
                    ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();
                    configAttrEditor.setAsText(grantedAuthorities);
                    ConfigAttributeDefinition definition = (ConfigAttributeDefinition) configAttrEditor
                            .getValue();
                    methodMap.put(resource.getValue(), definition);
                }
            }
            objectDefinitionSource = new DefaultMethodDefinitionSource(methodMatcher, methodMap);
        }
        return objectDefinitionSource;
    }
	
	 /**
     * 提供一个刷新MethodDefinitionSource的静态方法
     */
    public static void refresh() {
        objectDefinitionSource = null;
    }
    
    public void setObjectDefinitionSource(MethodDefinitionSource newSource) {
        objectDefinitionSource = newSource;
    }

}
